﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include <string>
#include <map>
#include "GcmpJournalInterface.h"
#include "OwnerPtr.h"

namespace gcmp
{
    class IJournalMessageSender;

    /// \brief 日志多APP协作客户端
    ///
    /// 适用满足以下条件的场景：
    /// 1、APP运行过程中会启动、调用另外一个APP，并在另外一个APP上做一些Ui操作
    /// 2、同一时间只能操作两个APP的其中一个，如下图：
    ///     APP_1   APP_2   '|'表示可操作的时机
    ///     |        
    ///     |        
    ///             |
    ///             |
    ///     |        
    ///     |        
    ///     |        
    ///     |        
    ///             |
    ///             |
    ///     |        
    ///     |        
    /// 3、同一时间，被启用的APP只能服务一个APP
    ///     拿上图举例，APP_2在由APP_1启用后，其他APP不可再启用APP_2，直至APP_1结束对APP_2的调用
    /// 4、APP在其生命周期内，不可以既调用另外的APP，又被另外的APP调用
    /// 
    /// 接口调用时机说明：
    ///
    /// 调用其他APP的APP：
    ///
    /// 1   调用接口：InitRequestContext
    ///     时机：启动另外一个APP之后，马上调用
    ///     作用：初始化日志环境
    ///
    /// 2   调用接口：SetJournalMessageSender
    ///     时机：在启用了另外一个APP，可以和另外一个APP创建通信通道的时候，且在请求协作之前
    ///     作用：设置用于与另外一个APP通信的消息发送器
    ///
    /// 3   调用接口：RequestCooperation
    ///     时机：在初始化日志环境、设置了通信通道且另外一个APP的操作环境也初始化好之后
    ///     作用：发起协作请求
    ///
    /// 4   调用接口：Handle
    ///     时机：收到另外一个APP的日志消息时
    ///     作用：处理另外一个APP发过来的日志消息
    ///
    /// 5   调用接口：FinishCooperation
    ///     时机：另外一个APP结束操作或者出现异常时
    ///     作用：结束协作
    /// 
    /// 被调用的APP：
    /// 
    /// 1   调用接口：SetJournalMessageSender
    ///     时机：在启用了另外一个APP，可以和另外一个APP创建通信通道的时候
    ///     作用：设置用于与另外一个APP通信的消息发送器
    /// 
    /// 2   调用接口：Handle
    ///     时机：收到另外一个APP的日志消息时
    ///     作用：处理另外一个APP发过来的日志消息
    class GCMP_JOURNAL_INTERFACE_EXPORT IJournalClient
    {
    public:
        virtual ~IJournalClient() {}

        /// \brief 获取客户端实例
        ///
        /// \return 客户端实例
        static IJournalClient* Get();

        /// \brief 请求协作前初始化日志环境
        ///
        /// 调用时机：启动另外一个APP之后，调用此接口初始化日志环境
        /// \return 运行结果，true:成功;false:失败
        virtual bool InitRequestContext() = 0;

        /// \brief 设置用于与另外一个APP通信的消息发送器
        ///
        /// 调用时机：在启用了另外一个APP，可以和另外一个APP创建通信通道的时候，启用其他APP的APP还需要限制在请求协作之前
        /// \param[in] opSender 日志消息发送器
        /// \return 运行结果，true:成功;false:失败
        virtual bool SetJournalMessageSender(OwnerPtr<IJournalMessageSender> opSender) = 0;

        /// \brief 发起协作请求
        ///
        /// 调用时机：在初始化日志环境、设置了通信通道且另外一个APP的操作环境也初始化好之后
        /// \return 运行结果，true:成功;false:失败
        virtual bool RequestCooperation() = 0;

        /// \brief 处理另外一个APP发过来的日志消息
        ///
        /// 调用时机：收到另外一个APP的日志消息时
        /// \param[in] message 日志消息
        /// \return 运行结果，true:成功;false:失败
        virtual bool Handle(const std::map<std::wstring, std::wstring> &message) = 0;

        /// \brief 结束协作
        ///
        /// 调用时机：另外一个APP结束操作或者出现异常时；只能在调用其他APP的APP的代码里调用
        /// \return 运行结果，true:成功;false:失败
        virtual bool FinishCooperation() = 0;
    };
}


